<?php
/**@method :创建文件
 * @param string $fileName
 * @return bool
 */
function createFile(string $fileName)
{
    if (file_exists($fileName)) {
        return false;
    }
    //监测目录是否存在
    if (!file_exists(dirname($fileName))) {
        //创建目录
        if (!mkdir($concurrentDirectory = dirname($fileName), 0777, true) && !is_dir($concurrentDirectory)) {
            throw new \RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory));
        }
    }
    if (touch($fileName)) {
        return true;
    } else {
        return false;
    }
}

/**
 * @method : 删除文件
 * @param string $fileName
 * @return bool
 */
function deleteFile(string $fileName)
{
    if (!file_exists($fileName) || !is_writable($fileName)) {
        return false;
    } else {
        unlink($fileName);
    }
}

/**
 * @method 复制文件
 * @param string $fileName
 * @param string $path
 * @return bool
 */
function copyFile(string $fileName, string $path)
{
    if (!file_exists($fileName)) {
        return false;
    } else {
        if (!is_dir($path)) {
            if (!mkdir($path, 0777, true) && !is_dir($path)) {
                throw new \RuntimeException(sprintf('Directory "%s" was not created', $path));
            }
        }
        $destName = $path . DIRECTORY_SEPARATOR . basename($fileName);
        if (file_exists($destName)) {
            return false;
        }
        if (copy($fileName, $path)) {
            return true;
        } else {
            return false;
        }

    }
}

/**
 * @method:重命名文件
 * @param string $fileName
 * @param string $newName
 * @return bool
 */
function renameFile(string $fileName, string $newName)
{
    $path = basename($newName);
    $destName = $path . DIRECTORY_SEPARATOR . basename($fileName);
    if (file_exists($fileName) and !file_exists($destName)) {
        rename($fileName, $newName);
        return true;
    } else {
        return false;
    }
}

/**
 * @method 剪切文件
 * @param string $fileName
 * @param string $path
 * @return bool
 */
function cutFile(string $fileName, string $path)
{
    if (!file_exists($fileName)) {
        return false;
    } else {
        $destPath = $path . DIRECTORY_SEPARATOR . $fileName;
        if (!is_dir($path)) {
            mkdir($path, 0777, true);
        }
        if (file_exists($destPath)) {
            echo "出现同名文件，退出程序！";
            return false;
        }
        if (rename($fileName, $destPath)) {
            return true;
        }
        return false;

    }
}

/**
 * @method 获取文件信息
 * @param string $fileName
 * @return bool
 */
function getFileInfo(string $fileName)
{
    date_default_timezone_set("Asia/Shanghai");
    if (file_exists($fileName) and is_readable($fileName)) {
        echo "文件类型为：" . filetype($fileName) . '<br>';
        echo "文件大小为：" . tansByte(filesize($fileName)) . '<br>';
        echo "文件创建时间为：" . date('Y-m-d H:i:s', filectime($fileName)) . '<br>';
        echo "文件修改时间为：" . date('Y-m-d H:i:s', fileatime($fileName));
    } else {
        echo "文件不存在";
        return false;
    }
}

/**
 * @method 字节转换成相应的大小
 * @param int $byte
 * @param int $precision
 * @return string
 */
function tansByte(int $byte, int $precision = 2)
{
    $kb = 1024;
    $mb = $kb * 1024;
    $gb = $mb * 1024;
    $tb = 1024 * $gb;
    if ($byte < $kb) {
        return $byte . 'B';
    } else if ($byte < $mb) {

        return round($byte / $kb, $precision) . 'KB';
    } elseif ($byte < $gb) {
        return round($byte / $mb, $precision) . 'MB';
    } else {
        return round($byte / $gb, $precision) . 'GB';
    }
}

/**
 * @method 读取文件
 * @param string $fileName
 * @return bool|false|string
 */
function readFiles(string $fileName)
{
    if (is_file($fileName) and is_readable($fileName)) {
        return file_get_contents($fileName);
    } else {
        return false;
    }
}

/**
 * @method 以数组的方式读取文件
 * @param string $fileName
 * @param bool $skip_empty_lines
 * @return array|bool|false
 */
function readFileArray(string $fileName, bool $skip_empty_lines = false)
{
    if (is_file($fileName) and is_readable($fileName)) {
        if ($skip_empty_lines === true) {
            return file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        }
        return file($fileName);
    } else {
        return false;
    }
}

/**
 * @method 将数据源写入文件，默认不会覆盖文件原有的数据
 * @param string $fileName
 * @param $data
 * @param bool $clear_flag
 * @return bool|string
 */
function writeFile(string $fileName, $data, bool $clear_flag = false)
{
    $dirname = dirname($fileName);
    if (!file_exists($dirname)) {
        mkdir($dirname, 0777, true);
    }
    if (is_file($fileName) and is_readable($fileName)) {
        if (filesize($fileName) > 0) {
            $srcData = file_get_contents($fileName);
        }
    }
    if (is_array($data) or is_object($data)) {
        $data = serialize($data);
    }
    $newDate = $srcData . $data;
    if (file_put_contents($fileName, $newDate) !== false) {
        return $newDate;
    } else {
        return false;
    }
}

/**
 * @method 将文件截取到指定长度
 * @param string $fileName
 * @param int $size
 * @return bool
 */
function truncateFile(string $fileName, int $size)
{
    if (is_file($fileName) and is_writable($fileName)) {
        $handle = fopen($fileName, 'r+');
        ftruncate($handle, $size);
        fclose($handle);
        echo "运行成功";
    } else {
        return false;
    }
}

/**
 * 下载文件
 * @method down_file
 * @param string $filename 文件名
 * @param array $allowDownExt 允许下载的文件类型
 * @return bool
 */
function down_file1(string $filename, array $allowDownExt = array('jpeg', 'jpg', 'png', 'gif', 'txt', 'html', 'php', 'rar', 'zip'))
{
    //检测下载文件是否存在，并且可读
    if (!is_file($filename) || !is_readable($filename)) {
        return false;
    }
    //检测文件类型是否允许下载
    $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    if (!in_array($ext, $allowDownExt)) {
        return false;
    }
    //通过header()发送头信息

    //告诉浏览器输出的是字节流
    header('Content-Type:application/octet-stream');

    //告诉浏览器返回的文件大小是按照字节进行计算的
    header('Accept-Ranges: bytes');

    $fileSize = filesize($filename);
    //告诉浏览器返回的文件大小
    header('Accept-Length: ' . $fileSize);

    //告诉浏览器文件作为附件处理，告诉浏览器最终下载完的文件名称
    header('Content-Disposition: attachment;filename=king_' . basename($filename));

    //读取文件中的内容

    //规定每次读取文件的字节数为1024字节，直接输出数据
    $read_buffer = 1024;
    $sum_buffer = 0;
    $handle = fopen($filename, 'rb');
    while (!feof($handle) && $sum_buffer < $fileSize) {
        echo fread($handle, $read_buffer);
        $sum_buffer += $read_buffer;
    }
    fclose($handle);
    exit;
}

/**
 * @method 文件上传
 * @param array $fileInfo
 * @param string $uploadPath
 * @param bool $imageFlag
 * @param int $maxSize
 * @return bool|mixed|string
 */
function uploadFile(array $fileInfo, string $uploadPath = './upload', bool $imageFlag = true, int $maxSize = 20971520)
{
    define('UPLOAD_ERRS', [
        'upload_max_fileSize' => "超过了php配置文件中upload_max_filesize选项的值",
        'form_max_size' => '超过了表单MAX_FILE_SIZE的值',
        'upload_file_partial' => '文件部分被上传',
        'no_upload_file_select' => '没有选择上传文件',
        'upload_system_error' => '系统错误',
        'no_allow_ext' => '非法文件类型',
        'exceed_max_size' => '超出允许上传的最大值',
        'not_true_image' => '不是真实图片',
        'not_http_post' => '不是http post方式上传的',
        'move_error' => '移动错误'
    ]);
    $allowExt = ['doc', 'docx', 'txt', 'jpg', 'rar', 'xls', 'xlst', 'mp4', 'zip'];
    //检测是否有错误
    print_r($fileInfo);
    if ($fileInfo['error'] === UPLOAD_ERR_OK) {
        //检测文件类型
        $ext = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, $allowExt)) {
            echo UPLOAD_ERRS['no_allow_ext'];
            return false;
        }
        if ($fileInfo['size'] > $maxSize) {
            echo UPLOAD_ERRS['exceed_max_size'];
            return false;
        }
        //检测是否是真实图片
        if (!$imageFlag) {
            if (@!getimagesize($fileInfo['tmp_name'])) {
                echo UPLOAD_ERRS['not_true_image'];
                return false;
            }
        }
        //判断是否是http post方式上传的
        if (!is_uploaded_file($fileInfo['tmp_name'])) {
            return UPLOAD_ERRS['not_http_post'];
        }
        //监测目录是否存在
        if (!is_dir($uploadPath)) {
            mkdir($uploadPath, 0777, true);
        }
        //生成唯一文件名，防止产生覆盖
        $uniName = md5(uniqid(microtime(true), true)) . '.' . $ext;
        $dest = $uploadPath . DIRECTORY_SEPARATOR . $uniName;
        //移动文件
        if (@!move_uploaded_file($fileInfo['tmp_name'], $dest)) {
            echo UPLOAD_ERRS['move_error'];
            return false;
        }
        echo '文件上传成功';
        return $dest;
    } else {
        switch ($fileInfo['error']) {
            case 1:
                $msg = UPLOAD_ERRS['upload_max_fileSize'];
                break;
            case 2:
                $msg = UPLOAD_ERRS['form_max_size'];
                break;
            case 3:
                $msg = UPLOAD_ERRS['upload_file_partial'];
                break;
            case 4:
                $msg = UPLOAD_ERRS['no_upload_file_select'];
                break;
            case 6:
            case 7:
            case 8:
                $msg = UPLOAD_ERRS['upload_system_error'];
                break;
        }
        echo $msg;
        return false;
    }
}

/**
 * @method 压缩单个文件
 * @param string $fileName
 * @return bool
 */
function zipFile(string $fileName)
{
    if (!is_file($fileName)) {
        return false;
    }
    $zip = new ZipArchive();
    $zipName = basename($fileName) . 'zip';
    if ($zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
        //打开压缩包，不存在则创建
        if ($zip->addFile($fileName)) {
            $zip->close();
            @unlink($fileName);
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

/**
 * @method 多文件压缩
 * @param string $zipName
 * @param mixed ...$files
 * @return bool
 */
function zipFiles(string $zipName, ...$files)
{
    $zipInfo = strtolower(pathinfo($zipName, PATHINFO_EXTENSION));
    if ($zipInfo !== 'zip') {
        return false;
    }
    $zip = new ZipArchive();
    if ($zip->open($zipName, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
        foreach ($files as $file) {
            if (is_file($file)) {
                $zip->addFile($file);
            }
        }
        $zip->close();
        return true;
    } else {
        echo "压缩失败";
        return false;
    }
}

/**
 * @method 解压文件
 * @param string $zipName
 * @param string $path
 * @return bool
 */
function unzipFile(string $zipName, string $path)
{
    if (!is_file($zipName)) {
        return false;
    }
    if (!is_dir($path)) {
        mkdir($path, 0777, true);
    }
    $zip = new ZipArchive();
    if ($zip->open($zipName)) {
        $zip->extractTo($path);
        $zip->close();
        return true;
    } else {
        return false;
    }
}

var_dump(unzipFile('index.zip', '.'));
